;   This program is free software: you can redistribute it and/or modify
;   it under the terms of the GNU General Public License as published by
;   the Free Software Foundation， either version 3 of the License， or
;   (at your option) any later version.
;
;   This program is distributed in the hope that it will be useful，
;   but WITHOUT ANY WARRANTY; without even the implied warranty of
;   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
;   GNU General Public License for more details.
;
;   You should have received a copy of the GNU General Public License
;   along with this program.  If not， see <http://www.gnu.org/licenses/>.
;
;字符串匹配模块
;用户输入的一个句子保存成文件，然后输入一个关键字进行查询。
;如果句中不包含关键字则显示"NOMATCH！"（红色字显示），
;如果句中包含关键字则显示“MATCH”（白色字显示）并重复显示这段文字，
;把匹配的字符用红色显示出来。
;
;其实十分钟的烂程式,为了windows7/8的垃圾dos搞了好一阵子,
;Xp/dos/win7/8都可正常了,只是使用了不常用的屏幕卷动….
;
;程序名称:find_ext.asm
;功能:找字符
;环境:16BIT DOS实模式(windows/dos或dosbox)
;编译器:MASM 5.1-6X 
;用法:看说明
;返回值:没有
;破坏寄存器:不适用
;
;--------------------------------------------------------
red_color equ 04h  ;red
key_word_max equ 10  ;keyword limit

DATAS SEGMENT
INPUT DB 'Input a String (save to file):$'
INPUT1 DB 10,13,'Input the key word (2-10 chars):$'
file_name db 'xcmpx.txt',0
file_L dw 0
match_str db 10,13,'MATCH',10,13,'$'
file_buff db 300 dup (0)
buffer db 255,0,255 dup (0)
error db 10,13,'Error !$'
no_match db  'NO MATCH !'
no_match_L equ  $ - offset no_match
key_word_L dw 0
DATAS ENDS

CODES SEGMENT
ASSUME CS:CODES,DS:DATAS   
start:
 mov ax,datas
 mov ds,ax
 mov es,ax
 cld
 mov ah,09
 mov dx,offset input
 int 21h
 mov ah,0Ah
 mov dx,offset buffer 
 int 21h
 mov cl,buffer + 1  ;get input length
 mov ch,0 
 jcxz next0   ;no input
 mov si,offset buffer + 2  ;point to input string
 add si,cx
 mov bp,cx ;save string length
 mov byte ptr [si],0  ;mask 0dh
 mov dx,offset  file_name
 mov cx,0
 mov ax,3c00h  ;create file
 int 21h
 jnc next1   ;ok
next0:   ;fail
 mov dx,offset error 
 mov ah,9
 int 21h
 jmp quit

next1:
 mov bx,ax  ;get handle
 mov dx,offset buffer + 2  ;input string
 mov cx,bp ;restore string length
 mov ah,40h  ;write file
 int 21h
 jc next0 ;error
 mov ah,3eh  ;close file
 int 21h
 mov ah,09
 mov dx,offset input1
 int 21h
 mov buffer,key_word_max ;10
 mov ah,0Ah   ;get keyword
 mov dx,offset buffer 
 int 21h   
 mov cl,buffer + 1   ;get length
 mov ch,0 
 cmp cl,2  
 jb next0   ;less then 2 , quit
 mov si,offset buffer + 2  ;keyword offset
 add si,cx 
 mov key_word_L,cx ;save string length
 mov byte ptr [si],0  ;mask 0dh
;read file
 mov dx,offset file_name
 mov ax,3d00h   ;read file 
 mov cx,0ffffh   ;normal attrib
 int 21h
 jc next0  ;fail
 mov bx,ax  ;get handle
 mov dx,offset file_buff
 mov cx,300   ;read length
 mov ah,3fh   ;read data
 int 21h
 jc next0   ;fail
 mov file_L,ax  ;ture length
 mov ah,3eh  ;close file
 int 21h

; comp keyword
 mov di,offset file_buff  ;point to  data
 mov si,offset buffer + 2  ;keyword 
 lodsb  ;first byte
 mov cx,file_L  ;file length
 mov bp,cx   ;save it
 mov bx,si   ;save it

next2:
 mov cx,bp  ;restore length
 repnz scasb  ;repeat scan  es:di , find al  
 mov bp,cx  ;stop while cx=0 or found !
 jnz next8 ;not found 
 ;first byte  
 mov cx,key_word_L   ;keyword length
 dec cx  ;bypass first byte
 mov si,bx  ;restore keyword offset
 rep cmpsb  ;compare 
 jnz  next2  ;not found, return to next scan

next3: ;found  !
 call cls
 mov dx,offset match_str
 mov ah,9
 int 21h

 mov si,offset file_buff    
 sub di,key_word_L  
 sub di,si
 mov cx,di  ;get length before keyword

next4:
 lodsb  
 mov ah,2
 mov dl,al
 int 21h
 loop next4     ;print all chars before keyword

 mov bp,key_word_L  ;keyword length 
 call print_red  ;print red

next6: ;print remain chars still Zero
 lodsb   
 or al,al  ;is it zero
 jz quit  ;yes , exit
 mov ah,2
 mov dl,al
 int 21h
 jmp short next6

next8:    ;not match
 call print_enter
 call cls
 mov si,offset no_match
 mov bp,no_match_L  
 call print_red ;print no match

quit:
 mov ah,7
 int 21h
 mov ah,4ch
 int 21h
;-------------------------
print_red:  ;si = offset , bp = count
 mov ah,3
 mov bh,0
 int 10h ;get cursor position
re_print:
 push dx ;save it
 lodsb
 mov ah,9
 mov bh,0
 mov cx,1
 mov bl,red_color
 int 10h  ;print 1 bytes with red color
 pop dx  ;restore cursor position 
 inc dl  ; forward 1 byte
 mov bh,0
 mov ah,2 ;get new cursor position
 int 10h     
 dec bp  ;next bytes
 jnz re_print 
 ret
;---------------------------- 
print_enter:
 mov dl,0dh
 mov ah,2
 int 21h
 mov dl,0Ah  ;print enter, next line
 ret
;---------------------------- 
cls:
  mov ax,0602h		     ;cls
  mov bh,7		     ;normal attribute
  mov cx,0		     ;top left
  mov dx,6079		     ;bottom right
  int 10h
  ret	

;------------------------------------------------------------------------------



CODES ENDS
END START



